package mop.controller;

import java.sql.Timestamp;
import java.util.List;

import mop.exception.BusinessRule1Exception;
import mop.exception.BusinessRule3Exception;
import mop.exception.IllegalDependencyException;
import mop.exception.IllegalDescriptionException;
import mop.exception.IllegalDuplicationException;
import mop.exception.IllegalIdException;
import mop.exception.IllegalMethodCallException;
import mop.model.World;
import mop.model.resource.Resource;
import mop.model.resource.ResourceInterface;
import mop.model.task.Task;
import mop.model.task.TaskInterface;
import mop.model.task.TaskMemento;

/**
 * Handler for the focus work use case (use case 11)
 * @author MOP Team 7
 */
public class ModifyTaskDetailsController extends UseCaseController {
	
	/**
	 * Constructor
	 * @see UseCaseController#UseCaseController(World)
	 */
	public ModifyTaskDetailsController(World world)
	{
		super(world);
	}
	
	/**
	 * @see	UseCaseController#getUserTasks()
	 */
	public List<TaskInterface> getUserTasks()
	{		
		return super.getUserTasks();
	}
	
	/**
	 * @see UseCaseController#getAllTasks()
	 */
	public List<TaskInterface> getAllTasks()
	{
		return super.getAllTasks();
	}
	
	/**
	 * @see UseCaseController#getAllResources()
	 */
	public List<ResourceInterface> getAllResources()
	{
		return super.getAllResources();
	}
	
	/**
	 * Inspector to see if a task can be modified
	 * @param id	Id of the task
	 * @return true if the task can be modified, false otherwise
	 * @throws IllegalIdException
	 * 	|@see UseCaseController#getTask(id)
	 */
	public boolean canBeModified(String id) throws IllegalIdException{
		Task task = getTask(id);
		return task.getStatus().updateDetails();
	}
	
	/**
	 * Modify task details
	 * 
	 * @param id			Id for task to edit
	 * @param description	The new task description
	 * @param start			The new start time for this task
	 * @param dur			The new duration it will take to complete this task
	 * @param deadline		The new deadline for this task
	 * @param dependencies	The new dependencies this task has
	 * @param resources		The new resources this task might use
	 * @throws Throwable 
	 * 
	 * @throws IllegalDeadlineException
	 * @see Task#modifyDetails(String, Timestamp, Timestamp, Timestamp, List, List)
	 * @effect Modify task details
	 * 	| 	t.modifyDetails(description, start, dur, deadline, tasklist, resourcelist)
	 * 
	 * @note When an error occurs, no changes will be applied, as task is rolled back to old state
	 */	
	public void updateTaskDetails(String id, Timestamp start,Timestamp dur,Timestamp deadline,List<String> dependencies,List<String> resources) 
		throws Throwable
	{
		if(!canBeModified(id))
			throw new IllegalMethodCallException("Task details can not be modified when failed");
		
		Task t = getTask(id); //get the task
		
		//Build lists from strings
		List<Resource> resourcelist =  getWorld().getResourceDataBase().convertFromIdToList(resources);
		List<Task> tasklist = getTaskList(dependencies);
		
		//Save memento for restoring
		TaskMemento memento = t.saveMemento();
		try{
			t.modifyDetails(start, dur, deadline, tasklist, resourcelist);
		}
		catch(Throwable e)
		{

			//restore task, so no changes are made
			t.restoreMemento(memento);
			
			throw e;
			
		}
	}
	
	
	/***************************************************************************
	 * 								Visit
	 ***************************************************************************/
	
	/**
	 * Make a CallBack to the visitor
	 * @param v the visitor
	 */
	public void visit(ControllerVisitor v)
	{
		v.action(this);
	}
}
